package com.demo.service.app.service.impl;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo.service.app.constants.SourceConstants;
import com.demo.service.app.dao.PerformerDao;
import com.demo.service.app.dao.PerformerImageDao;
import com.demo.service.app.dao.PerformerTabDao;
import com.demo.service.app.dao.TabCloudDao;
import com.demo.service.app.pojo.Performer;
import com.demo.service.app.pojo.PerformerImage;
import com.demo.service.app.pojo.PerformerTab;
import com.demo.service.app.pojo.TabCloud;
import com.demo.service.app.service.PerformerService;
import com.demo.service.app.util.SnowFlake;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;

@Service
@Slf4j
public class PerformerServiceImpl implements PerformerService {
    private final String baseUrl = "";

	@Resource
	private PerformerDao performerDao;
	@Resource
	private TabCloudDao tabCloudDao;
	@Resource
	private PerformerImageDao performerImageDao;
	@Resource
	private PerformerTabDao performerTabDao;
	
	@Override
	public int add(Performer performer) {
		performer.setCreateTime(LocalDateTime.now());
		return performerDao.add(performer);
	}
	@Override
//	@Transactional
	public int batchAdd() {
		String url = "";
		int startIndex = 1;
		int endIndex = 926; //926
		Document doc = null;
		
		//删除数据库中原记录(批量删除)
        performerDao.deleteBySource(SourceConstants.SOURCE_HOME);
        
        for(int i=startIndex; i<=endIndex; i++) {
            log.info("\n-------------------当前第【{}】页：开始处理--------------------",i);
            
            if(i==1) {
                url = baseUrl;
            }else {
                url = baseUrl+"page/"+i;
            }
            
            try {
                //会产生IO异常
                doc = Jsoup.connect(url).get();
            } catch (IOException e) {
                log.error(e.getMessage());
            }
            
            List<Performer> performerList = parsePerformersWeb(doc, SourceConstants.SOURCE_HOME, null);
            //保存至数据库
            performerDao.batchAdd(performerList);
            log.info("\n-------------------当前第【{}】页：处理结束--------------------",i);
        }
		return 0;
	}
	
	@Override
	public int addFromTab() {
		//删除原标签下的数据
		performerDao.deleteBySource(SourceConstants.SOURCE_TAB);
		//查询所有标签
		List<TabCloud> tabCloudList = tabCloudDao.queryAll();
		
		Document doc = null;
		
		//循环查询标签下的人员列表
		for(TabCloud tabCloud : tabCloudList) {
			log.info("\n-------------------处理开始，当前处理人员：{}--------------------",tabCloud.getName());
			
			try {				
				doc = Jsoup.connect(tabCloud.getLink()).get();
			} catch (SocketTimeoutException e) {
				log.error("\n*****************异常信息：{},【{}】***************", e.getMessage(), tabCloud.getName());
				continue;
			} catch (IOException e) {
				e.printStackTrace();
			}
			//当前页
			String currentPage = doc.selectFirst(".pagination").selectFirst(".current").attr("href");
			//分页处理
			while(true) {
				try {
					doc = Jsoup.connect(currentPage).get();
				} catch (SocketTimeoutException e) {
					log.error("\n**********异常信息：{},【{}】,当前页：{}*******", e.getMessage(), tabCloud.getName(),currentPage);
					break;
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				List<Performer> performerList = parsePerformersWeb(doc, SourceConstants.SOURCE_TAB, tabCloud.getId());
				//保存至数据库
				performerDao.batchAdd(performerList);
				
				//下一页信息
				Element e = doc.selectFirst(".pagination").selectFirst(".next");
				if(e==null) {
					break;
				}else {
					currentPage = e.attr("href");
				}
			}
			log.info("\n-------------------处理结束，当前处理人员：{}--------------------",tabCloud.getName());
		}
		
		return 0;
	}
	
	@Override
	public int addPerformerDetail() {
		//获取当前人员列表
		PageHelper.startPage(1, 100);
		List<Performer> list = performerDao.query();
		PageInfo<Performer> pageInfo = new PageInfo<Performer>(list);
		
		int pages = pageInfo.getPages();
		for(int i=1; i<=pages; i++) {
			PageHelper.startPage(i, 100);
			List<Performer> pList = performerDao.query();
			for(Performer p:pList) {
			    Document doc = null;
			    log.info("\n------------开始处理，当前链接：{}--------------", p.getDetailLink());
			    try {
                    doc = Jsoup.connect(p.getDetailLink()).get();
                } catch (IOException e) {
                    log.error("\n------------详情获取异常：{}------------",e.getMessage());
                    e.printStackTrace();
                }
                //获取图片和标签列表
                List<PerformerImage> imageList = getDetailImages(doc, p.getId());
                List<PerformerTab> tabList = getDetailTabs(doc, p.getId());
                //数据信息保存
                if(imageList!=null && imageList.size()>0) {
                    performerImageDao.batchAdd(imageList);
                }
                if(tabList!=null && tabList.size()>0) {
                    performerTabDao.batchAdd(tabList);
                }
                log.info("\n------------处理结束，当前链接：{}--------------", p.getDetailLink());
			}
		}
		return 0;
	}

	private List<Performer> parsePerformersWeb(Document doc, String source, String tabId) {
		List<Performer> performerList = new ArrayList<Performer>();
		SnowFlake snowFlake = new SnowFlake(2, 3);
		Element content = doc.getElementById("post_container");
		
		//提取数据至列表
		Elements links = content.getElementsByTag("li");
		for (Element link : links) {
			Performer performer = new Performer();
			
			String title = getTitle(link);
			String image = getImage(link);
			String detailLink = getDetailLink(link);
			
			performer.setId(String.valueOf(snowFlake.nextId()));
			performer.setTitle(title);
			performer.setImage(image);
			performer.setDetailLink(detailLink);
			performer.setTabId(tabId);
			performer.setSource(source);
			performer.setCreateTime(LocalDateTime.now());
			
			performerList.add(performer);
		}
		return performerList;
	}

	private String getTitle(Element e) {
		return e.selectFirst("div.article").selectFirst("h2").selectFirst("a").text();
	}
	
	private String getImage(Element e) {
		Element img = e.selectFirst("div.thumbnail").selectFirst("a").selectFirst("img");
		if(img==null) {
			return "error:img not exist!";
		}
		return img.attr("src");
	}
	private String getDetailLink(Element e) {
		return e.selectFirst("div.article").selectFirst("h2").selectFirst("a").attr("href");
	}
	
	private List<PerformerImage> getDetailImages(Document doc, String pId){
		List<PerformerImage> list = new ArrayList<PerformerImage>();
		SnowFlake snowFlake = new SnowFlake(2, 3);
		Element content = doc.selectFirst("#post_content").selectFirst("p");
		if(content==null) {
		    return list;
		}
		Elements images = content.select("img");
		for(Element e:images) {
			PerformerImage pImage = new PerformerImage();
			
			pImage.setId(String.valueOf(snowFlake.nextId()));
			pImage.setLink(e.attr("src"));
			pImage.setPId(pId);
			pImage.setCreateTime(LocalDateTime.now());
			list.add(pImage);
		}
		return list;
	}
	
	private List<PerformerTab> getDetailTabs(Document doc, String pId){
		List<PerformerTab> list = new ArrayList<PerformerTab>();
		SnowFlake snowFlake = new SnowFlake(2, 3);
		Element tags = doc.selectFirst(".article_tags").selectFirst(".tagcloud");
		if(tags==null) {
		    return list;
		}
		Elements tabs = tags.select("a");
		for(Element e:tabs) {
			PerformerTab pTab = new PerformerTab();
			
			pTab.setId(String.valueOf(snowFlake.nextId()));
			pTab.setName(e.text());
			pTab.setPId(pId);
			pTab.setCreateTime(LocalDateTime.now());
			list.add(pTab);
		}
		return list;
	}
}
